
#include "StdAfx.h"
#include "MySQL_DBStatement.h"
#include <LogService.h>

MySQL_DBStatement::MySQL_DBStatement( MySQL_DBSession* session ) : 
DBStatement( session )
{
	stmt_ = 0;
	param_count_ = 0;
	result_set_.reset();	
	bind_cursor_ = 0;
	memset( binds_, 0, sizeof( MYSQL_BIND ) * DEF_MAX_BIND );
	memset( bind_length_, 0, sizeof( unsigned long ) * DEF_MAX_BIND );		
	DBStatement::reset();
}

MySQL_DBStatement::~MySQL_DBStatement(){
}

int MySQL_DBStatement::executeUpdate(){
	if(! session_ )
		return -1;

	if( stmt_ ){
		if( mysql_stmt_bind_param( stmt_, binds_ ) ){
			error_log( (char*)__FUNCTION__, __LINE__ );
			return -1;
		}

		if( mysql_stmt_execute( stmt_ ) ){
			error_log( (char*)__FUNCTION__, __LINE__ );
			return -1;
		}

		return 0;
	}

	if( mysql_real_query( ((MySQL_DBSession*)session_)->getSession(), sql_, strlen( sql_ ) ) ){
		session_->set_error( 0, ( char* )sql_, ( char* )__FUNCTION__, __LINE__ );		
		return -1;
	}

	return 0;
}

DBResultSet* MySQL_DBStatement::executeQuery(){
	if(! session_ )
		return 0;

	if( mysql_real_query( ((MySQL_DBSession*)session_)->getSession(), sql_, strlen( sql_ ) ) ){
		session_->set_error( 0, sql_, ( char* )__FUNCTION__, __LINE__ );
		return 0;
	}
	
	result_set_.result_set_ = mysql_store_result( ((MySQL_DBSession*)session_)->getSession() );

	if(! result_set_.result_set_ ){
		session_->set_error( 0, sql_, (char*)__FUNCTION__, __LINE__ );
		return 0;
	}

	return (DBResultSet*)&result_set_;
}

int MySQL_DBStatement::prepare( int result_type ){
	return 0;
}

void MySQL_DBStatement::reset(){
	param_count_ = 0;	

	result_set_.reset();	

	if( stmt_ ){
		mysql_stmt_close( stmt_ );
		stmt_ = 0;
	}
	
	bind_cursor_ = 0;
	memset( binds_, 0, sizeof( MYSQL_BIND ) * DEF_MAX_BIND );
	memset( bind_length_, 0, sizeof( unsigned long ) * DEF_MAX_BIND );		
	DBStatement::reset();
}

DBSession* MySQL_DBStatement::getSession(){
	return 0;
}

bool MySQL_DBStatement::prepareStmt(){
	if(! stmt_ ){
		stmt_ = mysql_stmt_init( ((MySQL_DBSession*)session_)->getSession() );
		if(! stmt_ ){
			error_log( (char*)__FUNCTION__, __LINE__ );
			return false;
		}
		
		if( mysql_stmt_prepare( stmt_, sql_, strlen( sql_ ) ) ){
			error_log( (char*)__FUNCTION__, __LINE__ );
			return false;
		}

		param_count_ = mysql_stmt_param_count( stmt_ );
	}

	return true;
}

void MySQL_DBStatement::setByte( char& value, short flag ){		
	if(! prepareStmt() )
		return;

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_TINY;
	binds_[ bind_cursor_ ].buffer = (char*)&value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = 0;

	bind_cursor_++;	
}

void MySQL_DBStatement::set2Byte( short& value, short flag ){
	if(! prepareStmt() )
		return;

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_SHORT;
	binds_[ bind_cursor_ ].buffer = (char*)&value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = 0;

	bind_cursor_++;	
}

void MySQL_DBStatement::set4Byte( int& value, short flag ){
	if(! prepareStmt() )
		return;

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_LONG;
	binds_[ bind_cursor_ ].buffer = (char*)&value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = 0;

	bind_cursor_++;
}

void MySQL_DBStatement::set4Byte( unsigned int& value, short flag ){
	if(! prepareStmt() )
		return;

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_LONG;
	binds_[ bind_cursor_ ].buffer = (char*)&value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = 0;

	bind_cursor_++;
}

void MySQL_DBStatement::set8Byte( __int64& value, short flag ){
	if(! prepareStmt() )
		return;

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_LONGLONG;
	binds_[ bind_cursor_ ].buffer = (char*)&value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = 0;

	bind_cursor_++;
}

void MySQL_DBStatement::setFloat( float& value, short flag ){
	if(! prepareStmt() )
		return;

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_FLOAT;
	binds_[ bind_cursor_ ].buffer = (char*)&value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = 0;

	bind_cursor_++;
}

void MySQL_DBStatement::setString( char* value, short flag, int size ){
	if(! prepareStmt() )
		return;
	
	bind_length_[ bind_cursor_ ] = strlen( value );

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_STRING;
	binds_[ bind_cursor_ ].buffer = value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = &( bind_length_[ bind_cursor_ ] );
	binds_[ bind_cursor_ ].buffer_length= bind_length_[ bind_cursor_ ];

	bind_cursor_++;
}

void MySQL_DBStatement::setDate( char* value, short flag ){
	if(! prepareStmt() )
		return;

	bind_length_[ bind_cursor_ ] = strlen( value );

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_STRING;
	binds_[ bind_cursor_ ].buffer = value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = &( bind_length_[ bind_cursor_ ] );
	binds_[ bind_cursor_ ].buffer_length= bind_length_[ bind_cursor_ ];

	bind_cursor_++;
}

void MySQL_DBStatement::setMemory( char* value, int size, short flag ){
	if(! prepareStmt() )
		return;

	bind_length_[ bind_cursor_ ] = size;

	binds_[ bind_cursor_ ].buffer_type = MYSQL_TYPE_BLOB;
	binds_[ bind_cursor_ ].buffer = value;
	binds_[ bind_cursor_ ].is_null = 0;
	binds_[ bind_cursor_ ].length = &( bind_length_[ bind_cursor_ ] );
	binds_[ bind_cursor_ ].buffer_length = size;

	bind_cursor_++;
}

void MySQL_DBStatement::setNull(){
	if(! prepareStmt() )
		return;
}

void MySQL_DBStatement::setReal( double& value, int precision, int scale, short flag ){
	if(! prepareStmt() )
		return;
}

void MySQL_DBStatement::error_log( char* method, int line ){
	char* err = (char*)mysql_stmt_error( stmt_ );

	if(! err )
		return;

	LOG_ERR( LOG_SERVICE( "instance" )->Log("%s - %u - %s", method, line, err ) );	
}

int MySQL_DBStatement::is_procedure(){
	if( strstr( sql_, "call" ) )
		return 1;

	if( strstr( sql_, "CALL" ) )
		return 1;	

	return 0;
}
